/*
 * //Author: Karthic Kumar Sekar [A0092622]
 */

package sg.edu.nus.iss.team4ft.service;

import java.io.Serializable;

import java.util.Date;

import sg.edu.nus.iss.team4ft.exception.InvalidOperationException;
import sg.edu.nus.iss.team4ft.util.AppConstant;
import sg.edu.nus.iss.team4ft.util.DateUtil;

public abstract class ServiceSubscription implements Serializable{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private String serviceId = "";
	private String serviceName = "";
	private Date startDate;
	private Date endDate;
	private Double subscriptionCharge;
	
	public ServiceSubscription(Date startDate){
		setStartDate(startDate);
	}
	
	protected ServiceSubscription(ServiceSubscription serviceSubscription){
		this.serviceName = serviceSubscription.serviceName;
		this.serviceId = serviceSubscription.serviceId;
		this.startDate = serviceSubscription.startDate;
		this.endDate = serviceSubscription.endDate;
		this.subscriptionCharge = serviceSubscription.subscriptionCharge;
	}
	
	public void setStartDate(Date startDate) {
		this.startDate = startDate;
	}
	
	public Date getStartDate() {
		return startDate;
	}
	
	public void setEndDate(Date endDate) throws InvalidOperationException {		
		//End date is lesser than the Start date.
		if(this.endDate == null){
			if(DateUtil.dateIsBefore(endDate, startDate))
				throw(new InvalidOperationException(this.serviceName + AppConstant.DEACTIVATION_DATE_MSG + DateUtil.defaultFormat(endDate) + AppConstant.ACTIVATION_DATE_MSG + DateUtil.defaultFormat(startDate) + "]."));
			else
				this.endDate = endDate;				
		}
	}
	
	public Date getEndDate() {
		return endDate;
	}
	
	public void setSubscriptionCharge(Double subscriptionCharge) {
		this.subscriptionCharge = subscriptionCharge;
	}
	
	public Double getSubscriptionCharge(Date forMonth) throws CloneNotSupportedException {
		if(isSubscriptionActive(forMonth))
			return subscriptionCharge;
		else
			return 0.0;
	}
	
	public boolean isSubscriptionActive(Date forMonth){
		boolean isActive = false;
		
		if(DateUtil.dateMonthAndYearIsEqual(startDate, forMonth) || (getEndDate()!= null && DateUtil.dateMonthAndYearIsEqual(forMonth, getEndDate())))
			return true;
		
		//Check if the subscription is made before the date
		if(DateUtil.dateIsEqual(startDate, forMonth) || DateUtil.dateIsBefore(startDate, forMonth))
		{
			//there is no end date and hence the service is active
			if(getEndDate() == null)
				isActive = true;
			
			//check if the date falls below the end date if end date is not null
			//assumed: user may want to unsubscribe a plan for future date. 
			if(getEndDate()!= null && (DateUtil.dateIsEqual(forMonth, getEndDate()) || DateUtil.dateIsBefore(forMonth, getEndDate())))
				isActive = true;
		}
		
		return isActive;
	}
	
	public void unsubscribeService(Date unsubscriptionDate) throws InvalidOperationException{
	setEndDate(unsubscriptionDate);		
	}
	
	public boolean canInclude(ServiceSubscription service){
		return true;		
	}

	public String getServiceName() {
		return serviceName;
	}

	public void setServiceName(String serviceName) {
		this.serviceName = serviceName;
		generateServiceId();
	}

	public String getServiceId() {
		return serviceId;
	}

	public void setServiceId(String serviceId) {
		this.serviceId = serviceId;
	}
	
	public void generateServiceId() {
		this.serviceId = serviceName + DateUtil.format(DateUtil.getDate(), "yyMMddHHmmss");
	}
	
	@Override
	public String toString() {
		StringBuffer s = new StringBuffer();
		s.append(this.getServiceName());
		s.append("  ");
		s.append(AppConstant.ACTIVATE + DateUtil.defaultFormat(this.getStartDate()));
		if(this.getEndDate() != null)			
			s.append("  " + AppConstant.DEACTIVATE + DateUtil.defaultFormat(this.getEndDate()));
		return s.toString();
	}
}
